package com.ruicar.afs.cloud.risk.tortoise.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import com.ruicar.afs.cloud.risk.tortoise.components.GwtRefDataField;
import com.ruicar.afs.cloud.risk.tortoise.components.GwtRefDataFieldsCache;
import com.ruicar.afs.cloud.risk.tortoise.consts.GwtTortoiseConst;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Description
 * @Author Peng Jinbo
 * @Date 2020/07/28 19:44
 */
@UtilityClass
@Slf4j
public class RefDataUtil {



    /**
     * Author Peng Jinbo
     * Add ref data t
     *
     * @param <T> parameter
     * @param dto dto
     * @return the t
     */
    public <T> T addRefData(T dto) {
        addRef(dto);
        return dto;
    }

    /**
     * Author Peng Jinbo
     * Add *
     *
     * @param <T> parameter
     * @param dto dto
     */
    private <T> void addRef(T dto) {
        if (Objects.isNull(dto)) {
            return;
        }
        Class clz = dto.getClass();
        if (GwtRefDataFieldsCache.contains(clz)) {
            try {
                List<GwtRefDataField> fieldAndKeys = GwtRefDataFieldsCache.get(clz);
                JSONObject refData = new JSONObject();
                for (GwtRefDataField fieldAndKey : fieldAndKeys) {
                    if (fieldAndKey.isList()) {
                        addForList(fieldAndKey, dto);
                    } else if (fieldAndKey.isUseName()) {
                        addForFieldName(fieldAndKey, dto, refData);
                    } else if (fieldAndKey.isEntity()) {
                        addRef(fieldAndKey.readProp(dto));
                    } else if (GwtTortoiseConst.FIELD_NAME_REF_DATA.equals(fieldAndKey.getName())) {
                        setRefData(fieldAndKey, dto, refData);
                    } else {
                        translated(fieldAndKey, dto, refData);
                    }
                }
            } catch (Exception e) {
                log.error("字段翻译失败",e);
                throw new AfsBaseException("字段翻译失败");
            }
        }
    }

    /**
     * 设置refData属性
     *
     * @param refDataField ref data field
     * @param obj          obj
     * @param refData      ref data
     * @throws Exception exception
     * @Author Peng Jinbo Sets ref data *
     */
    private void setRefData(GwtRefDataField refDataField, Object obj, JSONObject refData) throws Exception {
        if (Objects.nonNull(refDataField) && CollectionUtil.isNotEmpty(refData)) {
            JSONObject oriRefData = (JSONObject) refDataField.readProp(obj);
            if (Objects.isNull(oriRefData)) {
                oriRefData = refData;
            } else {
                oriRefData.entrySet().forEach(ref -> refData.put(ref.getKey(), ref.getValue()));
            }
            refDataField.writeProp(obj, oriRefData);
        }
    }

    /**
     * Author Peng Jinbo
     * Translated *
     * 翻译
     *
     * @param fieldAndKey field and key
     * @param obj         obj
     * @param refData     ref data
     * @throws Exception exception
     */
    private void translated(GwtRefDataField fieldAndKey, Object obj, JSONObject refData) throws Exception {
        List<DicDataDto> dicList = new ArrayList<>();
        String dicKey = fieldAndKey.getDicKey();
        if (dicKey.indexOf(",") == -1) {
            Map<String, List<DicDataDto>> dicMap = DicHelper.getDicMaps(dicKey);
            dicList = dicMap.get(fieldAndKey.getDicKey());
        } else {
            // 多个 key 联合获取翻译值
            String[] keys = dicKey.split(",");
            for (String key : keys) {
                Map<String, List<DicDataDto>> dicMap = DicHelper.getDicMaps(key);
                if (CollectionUtil.isNotEmpty(dicMap.get(key))) {
                    dicList.addAll(dicMap.get(key));
                }
            }
        }
        if (CollectionUtil.isNotEmpty(dicList)) {
            String name = "";
            // 获取字典翻译值
            Object val = fieldAndKey.readProp(obj);
            if (!StrUtil.isBlank(fieldAndKey.getDefaultVal()) && StrUtil.isBlank(Convert.toStr(val))) {
                fieldAndKey.writeProp(obj, fieldAndKey.getDefaultVal());
                val = fieldAndKey.getDefaultVal();
            }
            if (Objects.nonNull(val)) {
                final Object compareVal = val;
                Optional<DicDataDto> optional= dicList.stream().filter(dic -> dic.getValue().equals(compareVal)).findFirst();
                if(optional.isPresent()){
                    name = optional.get().getTitle();
                }
                // 当前属性字典转换 例如 01是否 与 yesNo是否的转换
                if (StrUtil.isNotBlank(fieldAndKey.getTranslatedKey())) {
                    Map<String, List<DicDataDto>> dicMap = DicHelper.getDicMaps(fieldAndKey.getTranslatedKey());
                    if (CollectionUtil.isNotEmpty(dicMap.get(fieldAndKey.getTranslatedKey()))) {
                        List<DicDataDto> dataDtoList = dicMap.get(fieldAndKey.getTranslatedKey());
                        for (DicDataDto dicDataDto : dataDtoList) {
                            if(fieldAndKey.isTranslatedByKey() && dicDataDto.getValue().equals(val)){
                                name = dicDataDto.getTitle();
                                break;
                            }else if (dicDataDto.getTitle().equals(name)) {
                                val = dicDataDto.getValue();
                                fieldAndKey.writeProp(obj, val);
                                break;
                            }
                        }
                    }
                }
                if(StrUtil.isNotBlank(fieldAndKey.getWhetherDesc())){
                    if(GwtTortoiseConst.REF_DATA_YES.equals(val)){
                        name = fieldAndKey.getWhetherDesc();
                    }else{
                        name = "非" + fieldAndKey.getWhetherDesc();
                    }
                }

                RefDataConvert.convertKey(fieldAndKey,val,obj);

                // 设置翻译值
                if (StrUtil.isNotBlank(name)) {
                    refData.put(fieldAndKey.getJsonKey() + GwtTortoiseConst.FIELD_REF_TAIL, RefDataConvert.convertName(fieldAndKey,name));
                }
            }
        }else {
            log.warn("获取到的字典数据为空，dicType:{}", fieldAndKey.getDicKey());
        }
    }

    /**
     * Author Peng Jinbo
     * Add for list *
     * list属性处理
     *
     * @param fieldAndKey field and key
     * @param obj         obj
     * @throws Exception exception
     */
    private void addForList(GwtRefDataField fieldAndKey, Object obj) throws Exception {
        if (ClassUtil.isSimpleValueType(fieldAndKey.getListParameterType())) return;
        List list = (List) fieldAndKey.readProp(obj);
        if (CollectionUtil.isNotEmpty(list)) {
            for (Object objElement : list) {
                addRef(objElement);
            }
        }
    }

    /**
     * Author Peng Jinbo
     * Add for field name *
     * 使用当前字段名+name的字段作为当前字段的翻译值
     *
     * @param fieldAndKey field and key
     * @param obj         obj
     * @param refData     ref data
     */
    private void addForFieldName(GwtRefDataField fieldAndKey, Object obj, JSONObject refData) {
        // 使用当前实体字段名 + Name的字段值作为当前字段的翻译值
        // 省、市、品牌、样式类翻译用到
        Object val = null;
        if (ReflectUtil.hasField(obj.getClass(), fieldAndKey.getName() + GwtTortoiseConst.TRANSLATED_TAIL)) {
            Field provinceField = ReflectUtil.getField(obj.getClass(), fieldAndKey.getName() + GwtTortoiseConst.TRANSLATED_TAIL);
            val = ReflectUtil.getFieldValue(obj, provinceField);
        }
        if (StrUtil.isNotBlank(Convert.toStr(val))) {
            refData.put(fieldAndKey.getJsonKey() + GwtTortoiseConst.FIELD_REF_TAIL, val);
        }
    }

    class RefDataConvert{
        public static final Map<String,String> carTypeCodeConvert = new HashMap(){
            {
                put("00","01");
                put("01","04");
                put("02","12");
                put("03","13");
            }
        };

        public static final Map<String,String> repayFrequencyNameConvert = new HashMap(){
            {
                put("月付","月");
                put("年付","年");
            }
        };

        public static final Map<String,String> relationshipNameConvert = new HashMap(){
            {
                put("夫妻","夫-妻");
            }
        };

        public static Object convertKey(GwtRefDataField field,Object val,Object obj) throws Exception{
            Object convertResult =  val;
            if("tortoiseCarType".equals(field.getTranslatedKey()) && carTypeCodeConvert.containsKey(val)){
                convertResult = carTypeCodeConvert.get(val);
                field.writeProp(obj,convertResult);
            }
            return convertResult;
        }

        public static String convertName(GwtRefDataField field,String name){
            String convertName = name;
            if("tortoiseRepayFrequency".equals(field.getTranslatedKey()) && repayFrequencyNameConvert.containsKey(name)){
                convertName = repayFrequencyNameConvert.get(name);
            }else if("custRelation".equals(field.getDicKey()) && relationshipNameConvert.containsKey(name)){
                convertName = relationshipNameConvert.get(name);
            }
            return convertName;
        }

    }

}
